package com.example.yls.demoa;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;

/**
 * Created by yls on 2019/5/17.
 */

public class MyView extends View {
    private String matchId="123456";
    private int npanelwidth;//棋盘宽度
    private float nlineheight;//棋盘高度
    private int Max_LINE=10;//棋盘行数
    private int count_line=5;//5子连棋

    private Paint paint=new Paint();

    private Bitmap mWhitePiece;//白棋
    private Bitmap mBlackPiece;//黑棋

    //引入比例，让棋子大小是行高的4/3，这样有4/1的空隙
    private float radioPieceOfLineHeight=3*1.0f/4;

    //判断当前是否轮到白棋
    private boolean mIswhite=true;
    private ArrayList<Point>mwhiteArray=new ArrayList<>();
    private ArrayList<Point>mblackArray=new ArrayList<>();

    //判断游戏是否结束
    private boolean misGameOver;
    private boolean misWhiteWinner;

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //setBackgroundColor(0x44ff0000);
        //初始化画笔
        init();
    }

    private void init() {
        paint.setColor(0x88000000);
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setStyle(Paint.Style.STROKE);

        mWhitePiece= BitmapFactory.decodeResource(getResources()
        ,R.drawable.stone_w2);
        mBlackPiece=BitmapFactory.decodeResource(getResources(),
                R.drawable.stone_b1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //棋盘总长宽
       int widthsise=MeasureSpec.getSize(widthMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);

        int heightsize=MeasureSpec.getSize(heightMeasureSpec);
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);


        int width=Math.min(widthsise,heightsize);
        if (widthMode==MeasureSpec.UNSPECIFIED){
            width=heightsize;
        }else if (heightMode==MeasureSpec.UNSPECIFIED){
          width=widthsise;
        }
        setMeasuredDimension(width,width);
    }
//宽高确定之后会回调
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
         npanelwidth=w;
         //每一列的宽度
         nlineheight=npanelwidth*1.0f/Max_LINE;

        int pieceWidth= (int) (nlineheight*radioPieceOfLineHeight);//棋子的宽高
         mWhitePiece=Bitmap.createScaledBitmap
                 (mWhitePiece,pieceWidth,pieceWidth,false);
         mBlackPiece=Bitmap.createScaledBitmap
                 (mBlackPiece,pieceWidth,pieceWidth,false);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(misGameOver) return false;

        int action =event.getAction();
        if (action==MotionEvent.ACTION_UP){

            int x= (int) event.getX();
            int y= (int) event.getY();


            /*Point p=new Point(x,y);*///将用户点击的坐标储存下来，
                                     // 根据集合存储的值绘制棋子
            Point p=getValidPoint(x,y);
            //判断集合中的棋子是否存在
            if (mwhiteArray.contains(p)|| mblackArray.contains(p)){
                return false;
            }
            if (mIswhite){
               mwhiteArray.add(p);
            }else {
                mblackArray.add(p);
            }
            invalidate();
            mIswhite=!mIswhite;
            savaToBmob();
        }
        return true;
    }

    private void savaToBmob() {
        BmobQuery<wuzidata>wuzidataBmobQuery=new BmobQuery<>();
        wuzidataBmobQuery.addWhereEqualTo("matchId",matchId);
        wuzidataBmobQuery.findObjects(new FindListener<wuzidata>() {
            @Override
            public void done(List<wuzidata> list, BmobException e) {
                if (e==null&&list!=null&&list.size()>0){
                    wuzidata wuzidatas=list.get(0);
                    wuzidatas.setMblackArray(mblackArray);
                    wuzidatas.setMwhiteArray(mwhiteArray);
                    wuzidatas.setMisGameOver(misGameOver);
                    wuzidatas.setmIswhite(mIswhite);
                    wuzidatas.setMisWhiteWinner(misWhiteWinner);
                    wuzidatas.update(new UpdateListener() {
                        @Override
                        public void done(BmobException e) {

                        }
                    });

                }else {
                    wuzidata wuzidatas=new wuzidata();
                    wuzidatas.setMatchId(matchId);
                    wuzidatas.setMblackArray(mblackArray);
                    wuzidatas.setMwhiteArray(mwhiteArray);
                    wuzidatas.setMisGameOver(misGameOver);
                    wuzidatas.setmIswhite(mIswhite);
                    wuzidatas.setMisWhiteWinner(misWhiteWinner);
                    wuzidatas.save(new SaveListener<String>() {
                        @Override
                        public void done(String s, BmobException e) {

                        }
                    });
                }
            }
        });
    }

    private Point getValidPoint(int x, int y) {
        //将用户点击的点存储起来
        return new Point((int )(x/nlineheight),(int) (y/nlineheight));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制棋盘
        drawBoard(canvas);
        //绘制棋子
        drawPieces(canvas);
        //检查游戏是否结束
        checkGameOver();
    }
    //检查游戏是否结束
    private void checkGameOver() {
       boolean whiteWin= checkFive(mwhiteArray);
       boolean blackWin= checkFive(mblackArray);
       if (whiteWin||blackWin){

           misGameOver=true;
           misWhiteWinner=whiteWin;

           String text=misWhiteWinner?"白棋胜利":"黑棋胜利";
           Toast.makeText(getContext(),text,Toast.LENGTH_SHORT).show();

       }
    }

    private boolean checkFive(List<Point> points) {
        for (Point p:points){
            int x=p.x;
            int y=p.y;
            boolean win=checkH(x,y,points);//水平方向
            if (win)return true;
            win=cheV(x,y,points);
            if (win)return true;
            win=LeftT(x,y,points);
            if (win)return true;
            win=RightT(x,y,points);
            if (win)return true;
        }
        return false;
    }
   //水平方向的棋子
    private boolean checkH(int x, int y, List<Point> points) {
        int count =1;
        //左边
        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x-i,y))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;

        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x+i,y))){
                count++;
            }else {
                break;
            }
        }
       if (count==count_line)return true;
        return false;
    }
    //垂直方向的棋子
    private boolean cheV(int x, int y, List<Point> points) {
        int count =1;
        //下
        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x,y+i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;

        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x,y-i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;
        return false;
    }
    //左上方向的棋子
    private boolean LeftT(int x, int y, List<Point> points) {
        int count =1;
        //左上
        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x+i,y-i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;

        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x-i,y+i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;
        return false;
    }
    //右上方向的棋子
    private boolean RightT(int x, int y, List<Point> points) {
        int count =1;
        //右上变
        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x+i,y+i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;

        for (int i=1;i<count_line;i++){
            if (points.contains(new Point(x-i,y-i))){
                count++;
            }else {
                break;
            }
        }
        if (count==count_line)return true;
        return false;
    }

    //绘制棋子
    private void drawPieces(Canvas canvas) {
        //绘制白棋
        for (int i=0,n=mwhiteArray.size();i<n;i++){
            Point whitePoint=mwhiteArray.get(i);
            //白棋子的起始坐标
            canvas.drawBitmap(mWhitePiece,
                    (whitePoint.x+(1-radioPieceOfLineHeight)/2)*nlineheight,
                    (whitePoint.y+(1-radioPieceOfLineHeight)/2)*nlineheight,null);
        }
        //绘制黑棋
        for (int i=0,n=mblackArray.size();i<n;i++){
            Point blackPoint=mblackArray.get(i);
            //黑棋子的起始坐标
            canvas.drawBitmap(mBlackPiece,
                    (blackPoint.x+(1-radioPieceOfLineHeight)/2)*nlineheight,
                    (blackPoint.y+(1-radioPieceOfLineHeight)/2)*nlineheight,null);;
        }
    }
    //绘制棋盘
    private void drawBoard(Canvas canvas) {
        int w=npanelwidth;//棋盘宽度
        float lineheight=nlineheight;
        for (int i=0;i<Max_LINE;i++){
            int starx= (int) (lineheight/2);//横线初始坐标
            int endx= (int) (w-lineheight/2);//横线终止坐标

            int y= (int) ((0.5+i)*nlineheight);//y的坐标
            canvas.drawLine(starx,y,endx,y,paint);//棋盘横线
            canvas.drawLine(y,starx,y,endx,paint);//棋盘的纵线

        }
    }
    //再来一局
    public void ReStar(){
        mwhiteArray.clear();
        mblackArray.clear();
        misGameOver=false;
        misWhiteWinner=false;
        invalidate();

    }
    //Activity的重建和恢复,白子和黑子的集合存储
    private static final String instance="instance";
    private static final String instance_game_over="instance_game_over";
    private static final String instance_white_array="instance_white_array";
    private static final String instance_black_array="instance_black_array";


    @Nullable
    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle=new Bundle();
        bundle.putParcelable(instance,super.onSaveInstanceState());
        bundle.putBoolean(instance_game_over,misGameOver);
        bundle.putParcelableArrayList(instance_white_array,mwhiteArray);
        bundle.putParcelableArrayList(instance_black_array,mblackArray);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle){
            Bundle bundle= (Bundle) state;
            misGameOver=bundle.getBoolean(instance_game_over);
            mwhiteArray=bundle.getParcelableArrayList(instance_white_array);
            mblackArray=bundle.getParcelableArrayList(instance_black_array);
            super.onRestoreInstanceState(bundle.getParcelable(instance));
            return;
        }
        super.onRestoreInstanceState(state);
    }

    public void setData(wuzidata wuzidatas) {
        this.misGameOver=wuzidatas.getisMisGameOver();
        this.mIswhite=wuzidatas.getismIswhite();
        this.misWhiteWinner=wuzidatas.getisMisWhiteWinner();
        this.mwhiteArray=wuzidatas.getMwhiteArray();
        this.mblackArray=wuzidatas.getMblackArray();
        //刷新
        invalidate();
    }


}
